package com.sql.parse.ognl;

import com.sql.parse.PlaceHolder;
import org.apache.ibatis.ognl.OgnlContext;
import org.apache.ibatis.ognl.OgnlException;
import org.apache.ibatis.ognl.OgnlRuntime;
import org.apache.ibatis.ognl.PropertyAccessor;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * @author GWQ
 */
public class MyDynamicContext {

    public static final String PARAMETER_OBJECT_KEY = "_parameter";

    static {
        OgnlRuntime.setPropertyAccessor(ContextMap.class, new ContextAccessor());
    }

    protected Collection<PlaceHolder> placeHolders;
    private final ContextMap bindings;
    private final StringBuilder sqlBuilder = new StringBuilder();
    private int uniqueNumber = 0;

    public Collection<PlaceHolder> getPlaceHolders() {
        return placeHolders;
    }

    public void setPlaceHolders(Collection<PlaceHolder> placeHolders) {
        this.placeHolders = placeHolders;
    }

    //默认是hashMap
    public MyDynamicContext(Object parameterObject) {
        bindings = new ContextMap();
        bindings.put(PARAMETER_OBJECT_KEY, parameterObject);
    }

    //默认是hashMap
    public MyDynamicContext(Object parameterObject, Collection<PlaceHolder> placeHolders) {
        bindings = new ContextMap();
        bindings.put(PARAMETER_OBJECT_KEY, parameterObject);
        this.placeHolders = placeHolders;
    }

    public Map<String, Object> getBindings() {
        return bindings;
    }

    public void bind(String name, Object value) {
        bindings.put(name, value);
    }

    public void appendSql(String sql) {
        sqlBuilder.append(sql);
        sqlBuilder.append(" ");
    }

    public String getSql() {
        return sqlBuilder.toString().trim();
    }

    public int getUniqueNumber() {
        return uniqueNumber++;
    }

    static class ContextMap extends HashMap<String, Object> {
        private static final long serialVersionUID = 2977601501966151582L;

        @Override
        public Object put(String key, Object value) {
            return super.put(key, value);
        }

        @Override
        public Object get(Object key) {
            String strKey = (String) key;
            if (super.containsKey(strKey)) {
                return super.get(strKey);
            }

            return null;
        }
    }

    static class ContextAccessor implements PropertyAccessor {

        @Override
        public Object getProperty(Map context, Object target, Object name)
                throws OgnlException {
            Map map = (Map) target;

            Object result = map.get(name);
            if (result != null) {
                return result;
            }

            Object parameterObject = map.get(PARAMETER_OBJECT_KEY);
            if (parameterObject instanceof Map) {
                return ((Map) parameterObject).get(name);
            }

            return null;
        }

        @Override
        public void setProperty(Map context, Object target, Object name, Object value)
                throws OgnlException {
            Map map = (Map) target;
            map.put(name, value);
        }

        @Override
        public String getSourceAccessor(OgnlContext var1, Object var2, Object var3) {
            return null;
        }

        @Override
        public String getSourceSetter(OgnlContext var1, Object var2, Object var3) {
            return null;
        }


    }

   /* public static class MetaObjectFactory {

        private static final ObjectFactory objectFactory = new DefaultObjectFactory();
        private static final ObjectWrapperFactory objectWrapperFactory = new DefaultObjectWrapperFactory();
        private static final DefaultReflectorFactory defalultReflectorFactory = new DefaultReflectorFactory();

        public static MetaObject getMetaObject(Object object) {
            return MetaObject.forObject(object, objectFactory, objectWrapperFactory, defalultReflectorFactory);
        }

    }*/
}